﻿namespace ChinaUnicom.ViewModels
{
    using Avatar;
    using Avatar.Commands;
    using Avatar.Schedule;
    using ChinaUnicom.Controls;
    using ChinaUnicom.Models;
    using ChinaUnicom.Tasks;
    using System;
    using System.ComponentModel;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;

    public class LoginContext : PageContext, INotifyPropertyChanged
    {
        ITaskScheduler scheduler;

        public LoginContext()
        {
            scheduler = SchedulerFactory.Create(SchedulerType.Serial);
            scheduler.Error += OnSchedulerError;

            // schedule
            // 1. Create session
            scheduler.Schedule(GenerateCreateSessionTask());
            // 2. initialize the code image
            scheduler.Schedule(GenerateCodeImageTask());

            // restore number.
            if (!Account.IsDefault(Context.Current.Account))
            {
                mobile = Context.Current.Account.Mobile;
            }
        }

        ITask GenerateCreateSessionTask()
        {
            ITask task = new CreateSessionTask();
            task.Failed += OnCreateSessionFailed;

            return task;
        }

        ITask GenerateCodeImageTask()
        {
            ITask task = new CodeImageTask();
            task.Completed += OnImageStreamCallback;

            return task;
        }

        void OnSchedulerError(object sender, FailedEventArgs e)
        {
            Action<FailedEventArgs> schedulerErrorAction = args =>
            {
                Message.Tips(args.Exception.Message, "温馨提示");
            };

            schedulerErrorAction.UIThreadInvoke(e);
        }

        void OnCreateSessionFailed(object sender, FailedEventArgs e)
        {
            Action<FailedEventArgs> getCodeImageAction = args =>
            {
                Message.Tips(args.Exception.Message, "温馨提示");
            };

            getCodeImageAction.UIThreadInvoke(e);
        }

        void OnImageStreamCallback(object sender, EventArgs e)
        {
            Action<CodeImageTask> getCodeImageAction = task =>
            {
                BitmapImage bitmap = new BitmapImage();
                bitmap.SetSource(task.Stream);
                CodeSource = bitmap;
            };

            getCodeImageAction.UIThreadInvoke(sender as CodeImageTask);
        }

        Command loginCommand;
        public ICommand LoginCommand
        {
            get
            {
                if (loginCommand == null)
                {
                    loginCommand = new Command(param =>
                    {
                        Context.Current.Account.Mobile = Mobile;
                        Context.Current.Store();
                        Navigate(new Uri(string.Format("/Views/SigningPage.xaml?mobile={0}&password={1}&imgCode={2}", Mobile, Password, ImgCode), UriKind.Relative));
                    });

                    loginCommand.IsEnabled = false;
                }

                return loginCommand;
            }
        }

        Command resetCodeCommand;
        public ICommand ResetCodeCommand
        {
            get
            {
                if (resetCodeCommand == null)
                {
                    resetCodeCommand = new Command(param =>
                    {
                        // 获取验证码
                        scheduler.Schedule(GenerateCodeImageTask());
                    });
                }

                return resetCodeCommand;
            }
        }

        string mobile;
        public string Mobile
        {
            get { return mobile; }
            set
            {
                if (value != mobile)
                {
                    mobile = value;
                    NotifyPropertyChanged("Mobile"); 
                    CheckLoginabled();
                }
            }
        }

        string imgCode;
        public string ImgCode
        {
            get { return imgCode; }
            set
            {
                if (value != imgCode)
                {
                    imgCode = value;
                    NotifyPropertyChanged("ImgCode");
                    CheckLoginabled();
                }
            }
        }

        string password;
        public string Password
        {
            get { return password; }
            set
            {
                if (value != password)
                {
                    password = value;
                    NotifyPropertyChanged("Password"); 
                    CheckLoginabled();
                }
            }
        }

        ImageSource codeSource;
        public ImageSource CodeSource
        {
            get { return codeSource; }
            set
            {
                if (value != codeSource)
                {
                    codeSource = value;
                    NotifyPropertyChanged("CodeSource");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        void CheckLoginabled()
        {
            if (Mobile.IsNullOrEmpty() || Password.IsNullOrEmpty() || ImgCode.IsNullOrEmpty())
            {
                (LoginCommand as Command).IsEnabled = false;
            }
            else
            {
                (LoginCommand as Command).IsEnabled = true;
            }
        }
    }
}
